package api

import (
	"django_blog_gin/internal/dto"
	"django_blog_gin/internal/repository"
	"django_blog_gin/internal/svc"
	"django_blog_gin/internal/utils"
	"sort"

	"github.com/gin-gonic/gin"
)

type CategoryApi struct {
	svcCtx *svc.ServiceContext
}

func NewCategoryApi(svcCtx *svc.ServiceContext) *CategoryApi {
	return &CategoryApi{svcCtx: svcCtx}
}

func (i *CategoryApi) GetCategoryList(ctx *gin.Context) {
	limit := ctx.DefaultQuery("limit", "10")
	offset := ctx.DefaultQuery("offset", "0")
	name := ctx.DefaultQuery("name", "")
	categoryRepo := repository.NewCategoryRepo(i.svcCtx)
	total, err := categoryRepo.GetCategoryTotal(name)
	if err != nil {
		utils.ResponseError(ctx, 400, err.Error())
		return
	}
	categoryList, err := categoryRepo.GetCategoryList(limit, offset, name)
	if err != nil {
		utils.ResponseError(ctx, 400, err.Error())
		return
	}
	utils.ResponseSuccess(ctx, gin.H{
		"total": total,
		"list":  categoryList,
	}, "ok")
}

// 创建分类
func (i *CategoryApi) CreateCategory(ctx *gin.Context) {
	var req dto.CreateCategoryReq
	if err := ctx.ShouldBindJSON(&req); err != nil {
		utils.ResponseError(ctx, 400, err.Error())
		return
	}

	categoryRepo := repository.NewCategoryRepo(i.svcCtx)
	count, err := categoryRepo.CheckCategoryExists(req.Name)
	if err != nil {
		utils.ResponseError(ctx, 400, err.Error())
		return
	}
	if count > 0 {
		utils.ResponseError(ctx, 400, "分类已存在")
		return
	}

	err = categoryRepo.CreateCategory(&req)
	if err != nil {
		utils.ResponseError(ctx, 400, err.Error())
		return
	}
	utils.ResponseSuccess(ctx, nil, "ok")
}

func (i *CategoryApi) GetAllCategory(ctx *gin.Context) {
	categoryRepo := repository.NewCategoryRepo(i.svcCtx)
	categoryList, err := categoryRepo.GetAllCategory()

	var resp []dto.CategoryMix
	parentCategoryMap := make(map[int]*dto.CategoryMix)
	childCategoryMap := make(map[int][]int)
	for _, category := range categoryList {
		categoryMix := &dto.CategoryMix{
			ID:               category.Id,
			Name:             category.Name,
			Slug:             category.Slug,
			Index:            category.Index,
			ParentCategoryID: 0,
		}

		if category.ParentCategoryId != nil {
			categoryMix.ParentCategoryID = *category.ParentCategoryId
			childCategoryMap[*category.ParentCategoryId] = append(childCategoryMap[*category.ParentCategoryId], category.Id)
		}
		parentCategoryMap[category.Id] = categoryMix
	}

	for _, categoryMix := range parentCategoryMap {
		if categoryMix.ParentCategoryID == 0 {
			fillChildCategories(parentCategoryMap, childCategoryMap, categoryMix)
			resp = append(resp, *categoryMix)
		}
	}
	// 添加父分类按index排序
	sort.Slice(resp, func(i, j int) bool {
		return resp[i].Index > resp[j].Index
	})

	if err != nil {
		utils.ResponseError(ctx, 400, err.Error())
		return
	}
	utils.ResponseSuccess(ctx, resp, "ok")
}

// fillChildCategories 递归填充子分类
func fillChildCategories(categoryMap map[int]*dto.CategoryMix, childMap map[int][]int, parentMix *dto.CategoryMix) {
	if childIds, exists := childMap[parentMix.ID]; exists {
		// 创建临时子分类列表
		var tempChildCategories []dto.CategoryMix

		for _, childId := range childIds {
			if childCategory, exists := categoryMap[childId]; exists {
				// 创建子分类的副本
				childCopy := *childCategory
				childCopy.ChildCategoryList = []dto.CategoryMix{}

				// 创建临时的parentMix来递归填充子分类的子分类
				tempParent := &dto.CategoryMix{
					ID:                childCopy.ID,
					Name:              childCopy.Name,
					Slug:              childCopy.Slug,
					Index:             childCopy.Index,
					ChildCategoryList: []dto.CategoryMix{},
				}
				// 递归填充子分类的子分类
				fillChildCategories(categoryMap, childMap, tempParent)

				childCopy.ChildCategoryList = tempParent.ChildCategoryList

				// 将子分类添加到父分类中
				parentMix.ChildCategoryList = append(parentMix.ChildCategoryList, childCopy)
			}
		}
		sort.Slice(tempChildCategories, func(i, j int) bool {
			return tempChildCategories[i].Index < tempChildCategories[j].Index
		})
	}
}

// updateCategoryIndex 更新分类索引
func (i *CategoryApi) updateCategory(ctx *gin.Context) {
	var req dto.UpdateCategoryReq
	if err := ctx.ShouldBindJSON(&req); err != nil {
		utils.ResponseError(ctx, 400, err.Error())
		return
	}
	// 检查分类是否存在
	categoryRepo := repository.NewCategoryRepo(i.svcCtx)
	count, err := categoryRepo.CheckCategoryExists(req.Name)
	if err != nil {
		utils.ResponseError(ctx, 400, err.Error())
		return
	}
	if count == 0 {
		utils.ResponseError(ctx, 400, "分类不存在")
		return
	}

	err = categoryRepo.UpdateCategory(&req)
	if err != nil {
		utils.ResponseError(ctx, 400, err.Error())
		return
	}
	utils.ResponseSuccess(ctx, nil, "ok")
}
